<template>
  <div style="width: 100%;overflow-y:scroll;height: calc(100vh - 70px)">
    <div class="modern-forms" style="margin-top: 120px">
      <div class="modern-container">
        <form style="text-align: left">
          <fieldset>
            <div class="mdn-group">
              <label class="field-group mdn-upload">
                <input v-model="imgpath" type="text" class="mdn-input" placeholder="no file selected" @click="selectImg" readonly>
                <label class="mdn-label">File Load</label>
                <span class="mdn-bar"></span>
                <span class="mdn-button btn-primary"> Choose Image </span>
              </label>
            </div>
            <template v-if="imgpath">
              <div class="form-row">
                <div class="col col-6">
                  <div class="field-group mdn-select">
                    <select name="select" v-model="linearfilter">
                      <option value="null">无</option>
                      <option value="average">均值滤波器</option>
                      <option value="gauss">高斯滤波器</option>
                    </select>
                    <label class="mdn-label">Smoothing Spatial Filters</label>
                    <span class="mdn-bar"></span>
                  </div>
                  <div class="field-group mdn-select">
                    <select name="select" v-model="nonlinearfilter">
                      <option value="null">无</option>
                      <option value="middle">中值滤波</option>
                      <option value="max">最大值滤波</option>
                      <option value="min">最小值滤波</option>
                    </select>
                    <label class="mdn-label">Order-Statistic (Nonlinear) Filters</label>
                    <span class="mdn-bar"></span>
                  </div>
                  <div class="mdn-group">
                    <label class="field-group mdn-upload">
                      <label class="mdn-label">Origin Image</label>
                      <img id="originImg"/>
                    </label>
                    <label class="field-group mdn-upload">
                      <label class="mdn-label">Filter Processing Image</label>
                      <canvas id="intensityImg"/>
                    </label>
                  </div>
                </div><!-- end col-4 -->
                <div class="col col-6">
                  <label class="field-group mdn-upload">
                    <label class="mdn-label">Filter</label>
                    <svg width="150" height="150">
                      <g v-for="(row, xi) in filterMat" :key="xi">
                        <g v-for="(item,yi) in row" :key="yi">
                          <rect width="50" height="50" fill="none" :x="xi*50" :y="yi*50" stroke="black" stroke-width="1"></rect>
                          <text :x="xi*50 + 25" :y="yi*50 + 25" text-anchor="middle" dominant-baseline="middle">{{item}}</text>
                        </g>
                      </g>
                    </svg>
                  </label>
                </div><!-- end col-8 -->
              </div><!-- end form-row -->
            </template>
          </fieldset>
        </form>
      </div><!-- modern-container -->
    </div><!-- modern-forms -->
  </div>
</template>

<script>
import * as d3 from "d3";

export default {
  name: "c3q2",
  data(){
    return{
      linearfilter:'null',
      nonlinearfilter:'null',
      weight:null,
      filterMat:[['NaN','NaN','NaN'],['NaN','NaN','NaN'],['NaN','NaN','NaN']],
      imgpath:null
    }
  },
  watch:{
    linearfilter(val){
      this.nonlinearfilter = 'null'
      if(val !== 'null') {
        if(val === 'average'){
          this.weight = [1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9]
          this.filterMat = [['1/9','1/9','1/9'],['1/9','1/9','1/9'],['1/9','1/9','1/9']]
        }
        if(val === 'gauss'){
          this.weight = [1/16,2/16,1/16,2/16,4/16,2/16,1/16,2/16,1/16]
          this.filterMat = [['1/16','2/16','1/16'],['2/16','4/16','2/16'],['1/16','2/16','1/16']]
        }
        this.drawImageWeight()
      }
    },
    nonlinearfilter(val){
      this.linearfilter = 'null'
      if(val !== 'null') {
        this.drawImageOrder()
      }
    }
  },
  methods:{
    selectImg(){
      let input = document.createElement('input');
      input.type = 'file';
      return new Promise(function (resolve) {
        input.onchange = function(ev) {
          resolve(ev.target.files[0])
          return false;
        };
        input.click();
      }).then(file=>{
        this.imgpath = file.path
        return new Promise(function (resolve) {
          var reader = new FileReader();
          reader.onload = function(e){
            let img = document.getElementById('originImg')
            img.src = e.target.result
            img.onload = ()=>resolve()
          }
          reader.readAsDataURL(file);
        })
      })
    },
    drawImageWeight(){
      function getLocal(x,y,c,width,height,arr){
        const maper = (i,j)=>arr[(j*width+i)*4+c]
        let a11 = x > 0 && y > 0 ? maper(x - 1,y - 1) : 0, a12 = y > 0 ? maper(x,y - 1) : 0, a13 = x + 1 < width && y > 0 ? maper(x + 1,y - 1) : 0,
            a21 = x > 0 ? maper(x - 1,y) : 0, a22 = maper(x,y), a23 = x + 1 < width ? maper(x + 1,y) : 0,
            a31 = x > 0 && y + 1 < height ? maper(x - 1,y + 1) : 0, a32 = y + 1 < height ? maper(x,y + 1) : 0, a33 = x + 1 < width && y + 1 < height ? maper(x + 1,y + 1) : 0;
        return [a11,a12,a13,a21,a22,a23,a31,a32,a33]
      }
      let weight = this.weight
      let img = document.getElementById('originImg')
      let canvas = document.getElementById('intensityImg')
      canvas.width = img.width;
      canvas.height = img.height;
      let ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0);
      let imageData = ctx.getImageData(0,0,img.width,img.height)
      for(let i = 0;i < img.height;i++){
        for (let j = 0; j < img.width;j++){
          imageData.data[(i*img.width + j)*4] = getLocal(j,i,0,img.width,img.height,imageData.data).reduce((total,curV,curI)=>total+curV*weight[curI],0)
          imageData.data[(i*img.width + j)*4+1] = getLocal(j,i,1,img.width,img.height,imageData.data).reduce((total,curV,curI)=>total+curV*weight[curI],0)
          imageData.data[(i*img.width + j)*4+2] = getLocal(j,i,2,img.width,img.height,imageData.data).reduce((total,curV,curI)=>total+curV*weight[curI],0)
        }
      }
      ctx.clearRect(0,0,img.width,img.height);
      ctx.putImageData(imageData,0,0)
    },
    drawImageOrder(){
      function getLocal(x,y,c,width,height,arr){
        const maper = (i,j)=>arr[(j*width+i)*4+c]
        let a11 = x > 0 && y > 0 ? maper(x - 1,y - 1) : 0, a12 = y > 0 ? maper(x,y - 1) : 0, a13 = x + 1 < width && y > 0 ? maper(x + 1,y - 1) : 0,
            a21 = x > 0 ? maper(x - 1,y) : 0, a22 = maper(x,y), a23 = x + 1 < width ? maper(x + 1,y) : 0,
            a31 = x > 0 && y + 1 < height ? maper(x - 1,y + 1) : 0, a32 = y + 1 < height ? maper(x,y + 1) : 0, a33 = x + 1 < width && y + 1 < height ? maper(x + 1,y + 1) : 0;
        return [a11,a12,a13,a21,a22,a23,a31,a32,a33]
      }
      let img = document.getElementById('originImg')
      let canvas = document.getElementById('intensityImg')
      canvas.width = img.width;
      canvas.height = img.height;
      let ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0);
      const filter = (function (type){
        if (type === 'max') return arr => arr.reduce((res,curV)=>Math.max(res,curV),Number.MIN_VALUE)
        if (type === 'min') return arr => arr.reduce((res,curV)=>Math.min(res,curV),Number.MAX_VALUE)
        if (type === 'middle') return arr => arr.sort()[4]
      })(this.nonlinearfilter)
      let imageData = ctx.getImageData(0,0,img.width,img.height)
      let imageData2 = ctx.getImageData(0,0,img.width,img.height)
      for(let i = 0;i < img.height;i++){
        for (let j = 0; j < img.width;j++){
          imageData2.data[(i*img.width + j)*4] = filter(getLocal(j,i,0,img.width,img.height,imageData.data))
          imageData2.data[(i*img.width + j)*4+1] = filter(getLocal(j,i,1,img.width,img.height,imageData.data))
          imageData2.data[(i*img.width + j)*4+2] = filter(getLocal(j,i,2,img.width,img.height,imageData.data))
        }
      }
      ctx.clearRect(0,0,img.width,img.height);
      ctx.putImageData(imageData2,0,0)
    }
  }
}
</script>

<style scoped>

</style>